package com.wh.wisdomsite.xbox.server.listener;

import com.wh.wisdomsite.xbox.common.Constants;
import com.wh.wisdomsite.xbox.server.session.ServerSessionUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.*;


/***
 * ServerSession会话管理
 * @Package com.wh.wisdomsite.xbox.server.listener
 * @author 丁奕
 * @date 2018年8月29日 下午15:33
 * @Copyright 个人版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2018
 * @version V1.0
 */
public class ServerSessionListener implements HttpSessionListener{
	
	private static final Log logger = LogFactory.getLog(ServerSessionListener.class);

    /**
     * 用户和Session绑定关系  key为sessionId，value为HttpSession，使用static，定义静态变量，使之程序运行时，一直存在内存中。
     */
	private static Map<String, HttpSession> sessionMap = new HashMap<String, HttpSession>(1000);

    /**
     * 获取在线的sessionMap
     */
    public static Map<String, HttpSession> getSessionMap() {
		return sessionMap;
	}

    /**
     * HttpSessionListener中的方法，在创建session
     */
	public void sessionCreated(HttpSessionEvent event) {
		logger.info("sessionCreated-->>创建会话 " + event.getSession().getId());
	}

    /**
     * SessionListener中的方法，回收session时,删除sessionMap中对应的session
     */
	public void sessionDestroyed(HttpSessionEvent event) {
		logger.debug("sessionDestroyed-->>会话销毁 " + event.getSession().getId());
		logger.debug("sessionDestroyed-->>移除会话缓存集合 " + event.getSession().getId());
		getSessionMap().remove(event.getSession().getId());
	}

    /**
     * 增加用户到session集合中  key = sessionId  value = HttpSession
     */
	public static void addUserSession(HttpSession session) {
		logger.debug("addUserSession-->>添加会话缓存集合 " + session.getId());
		getSessionMap().put(session.getId(), session);
	}

    /**
     * 从sessionMap中移除指定sessionId会话
     * @param sessionId
     */
	public static void removeSession(String sessionId) {
		logger.debug("removeSession-->>移除会话缓存集合 " + sessionId);
		getSessionMap().remove(sessionId);
	}

    /**
     * 判断sessionMap中存在
     */
	public static boolean containsKey(String key) {
		return getSessionMap().containsKey(key);
	}

    /**
     * 获取在线sessionMap中的SessionId
     */
	public static Iterator<String> getSessionMapKeySetIt() {
		return getSessionMap().keySet().iterator();
	}


    /**
     * 得到在线用户会话集合
     */
	public static List<HttpSession> getAllOnlineUserSession() {
		//创建集合
		List<HttpSession> onlineSession = new ArrayList<HttpSession>();
		//获取本地缓存数据的KeySet 即sessionId集合
		Iterator<String> iterator = getSessionMapKeySetIt();
		while (iterator.hasNext()) {
			//获取会话sessionId
			String sessionId = iterator.next();
			//获取HttpSession
			HttpSession httpSession = getSessionMap().get(sessionId);
			//添加到集合
			onlineSession.add(httpSession);
		}
			return onlineSession;
	}


    /**
     * 得到本地缓存所有会话数据，并返回Map集合(key为用户ID,value为会话ID)
     */
	public static Map<String, String> getUserSessionMap() {
		//创建集合数据
		Map<String, String> userSessionMap = new HashMap<String, String>();
		//获取本地缓存数据的KeySet 即sessionId集合
		Iterator<String> iterator = getSessionMapKeySetIt();
		logger.debug("getUserSessionMap-->>获取缓存用户会话[开始]");
		while (iterator.hasNext()) {
			//获取会话sessionId
			String sessionId = iterator.next();
			logger.debug("getUserSessionMap-->>获取缓存用户会话 sessionId = " + sessionId);
			//获取HttpSession
			HttpSession httpSession = getSessionMap().get(sessionId);
			if(null != httpSession){
				//获取当前HttpSession会话下用户
				Object sessionObj = httpSession.getAttribute(Constants.SERVER_SESSION_USER);
				if(null != sessionObj){
					//转换成ServerSessionUser
					ServerSessionUser serverSessionUser = (ServerSessionUser) sessionObj;
					if (null != serverSessionUser) {
						if(null != serverSessionUser.getUser().getUsId()){
							//存放在本地缓存集合中
							userSessionMap.put(serverSessionUser.getUser().getUsId().toString().trim(), sessionId);
						}
					}
				}
			}
		}
		logger.debug("getUserSessionMap-->>获取缓存用户会话[结束]");
		return userSessionMap;
	}


    /**
     * 根id从本地会话删除
     */
	public synchronized static void removeSessionUser(String id, String session_id) {
		//获取本地缓存会话数据
		Map<String, String> userSessionMap = getUserSessionMap();
		logger.debug("removeSessionUser-->>删除用户缓存集合会话/会话失效[开始]");
		if(null != userSessionMap && userSessionMap.size() > 0){
			logger.debug("缓存用户会话 id = " + id);
			if (userSessionMap.containsKey(id)) {
				//获取会话sessionId
				String sessionId = userSessionMap.get(id);
				logger.debug("removeSessionUser-->>缓存用户集合存在 id = " + id);
				logger.debug("removeSessionUser-->>会话 sessionId = " + sessionId);
				//同一浏览器【会话标识相同】
				if(sessionId.equals(session_id)){
					//从本地缓存中移除
					getSessionMap().remove(sessionId);
					logger.debug("removeSessionUser-->>【同一浏览器】移除缓存用户集合 sessionId = " + sessionId);
				}
				//不同浏览器【会话标识不同】
				else{
					//从本地缓存中销毁session
					getSessionMap().get(sessionId).invalidate();
					//从本地缓存中移除
					getSessionMap().remove(sessionId);
					logger.debug("removeSessionUser-->>【不同浏览器】移除缓存用户集合 sessionId = " + sessionId);
					logger.debug("removeSessionUser-->>【不同浏览器】会话销毁" + sessionId);
				}
			}
			logger.debug("SessionListener-->>removeSessionUser-->>删除用户缓存集合会话/会话失效[结束]");
		}
	}


    /**
     * 退出登录时，清楚缓存数据和session失效
     */
	public synchronized static void removeLoginOutuser(String id, String session_id) {
		//获取本地缓存会话数据
		Map<String, String> userSessionMap = getUserSessionMap();
		if(null != userSessionMap && userSessionMap.size() > 0){
			logger.debug("removeLoginOutuser-->>退出登录[开始]");
			if (userSessionMap.containsKey(id)) {
				//获取会话sessionId
				String sessionId = userSessionMap.get(id);
				logger.debug("removeLoginOutuser-->>缓存用户会话集合存在id = " + id);
				logger.debug("removeLoginOutuser-->>缓存用户会话集合存在sessionId = " + sessionId);
				//同一浏览器【会话标识相同】
				if(sessionId.equals(session_id)){
					//从本地缓存中销毁session
					getSessionMap().get(sessionId).invalidate();
					//从本地缓存中移除
					getSessionMap().remove(sessionId);
					logger.debug("removeLoginOutuser-->>会话失效");
					logger.debug("removeLoginOutuser-->>缓存用户会话集合移除");
				}
				logger.debug("removeLoginOutuser-->>退出登录[结束]");
			}
		}
	}


    /**
     * 判断该用户是否已重复登录，使用 同步方法，只允许一个线程进入，才好验证是否重复登录
     */
	public synchronized static boolean checkHasLogin(ServerSessionUser serverSessionUser) {
			boolean falg = false;
			try {
				//获取SessionKey
				Iterator<String> iterator = getSessionMapKeySetIt();
				logger.debug("checkHasLogin-->>检测用户是否登录[开始]");
				while (iterator.hasNext()) {
					//获取会话编号
					String sessionId = iterator.next();
					logger.debug("checkHasLogin-->>获取缓存用户会话集合sessionId = " + sessionId);
					//根据会话编号获取HttpSession
					HttpSession httpSession = getSessionMap().get(sessionId);
					if(null != httpSession){
						Object objSysUser = httpSession.getAttribute(Constants.SERVER_SESSION_USER);
						if(null != objSysUser){
							ServerSessionUser sessionUser = (ServerSessionUser) objSysUser;
							if (null != sessionUser) {
								if (sessionUser.getUser().getUsId().equals(serverSessionUser.getUser().getUsId())) {
									falg = true;
									logger.debug("checkHasLogin-->>检测用户已登录");
									break;
								}
							}
						}
					}
				}
				if(!falg){
					logger.debug("checkHasLogin-->>检测用户未登录");
				}
				logger.debug("checkHasLogin-->>检测用户是否登录[结束]");
			}catch (Exception e) {
				e.printStackTrace();
				logger.error("checkHasLogin-->>异常-->>" + e.getMessage());
				falg = false;
			}
				return falg;
	}
}
